package com.ys.otms.services.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ys.otms.dao.IShipDao;
import com.ys.otms.dao.ITransportPlanDao;
import com.ys.otms.dto.*;
import com.ys.otms.services.IDeductionsServices;
import com.ys.otms.services.ITransportPlanServices;
import com.ys.otms.utils.*;
import com.ys.otms.utils.download.IDownloadHandler;
import com.ys.otms.utils.download.impl.TransportDownloadHandler;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class TransportPlanServiceImpl implements ITransportPlanServices {

    private static Logger logger = LoggerFactory.getLogger(TransportPlanServiceImpl.class);

    private static String URL = "https://restapi.amap.com/v3/geocode/regeo?location=ZB&output=JSON&key=3efa2c4d5ab9b7995b8306774ef73471&batch=PL";

    @Autowired
    private ITransportPlanDao iTransportPlanDao;

    @Autowired
    private IShipDao iShipDao;

    @Autowired
    private IDeductionsServices iDeductionsServices;

    /**
     * 查询计划列表(参数，公司id，运输计划状态，和计划分类id)
     *
     * @param request <br/>
     * @return <br/>
     * @throws Exception <br/>
     */
    @Override
    public JSONObject queryTransportPlan(HttpServletRequest request, JSONObject obj) {
        logger.info("TransportPlanServiceImpl queryTransportPlan start obj:{}", obj);
        int companyId = Integer.parseInt((String) request.getSession().getAttribute("SESSION_COMPANY_ID"));
        TransportPlanDto transportPlanDto = new TransportPlanDto();
        transportPlanDto.setCompanyId(companyId);
        String transportState = JsonUtil.getJSONObjectString2(obj, "transportState");
        if (StringUtil.isNotEmpty(transportState)) {
            transportPlanDto.setTransportState(transportState);
        }

        String planClassId = JsonUtil.getJSONObjectString2(obj, "planClassId");
        if (StringUtil.isNotEmpty(planClassId)) {
            transportPlanDto.setPlanClassId(planClassId);
        }

        String planName = JsonUtil.getJSONObjectString2(obj, "planName");
        if (StringUtil.isNotEmpty(planName)) {
            transportPlanDto.setPlanName(planName);
        }

        String huoZhuName = JsonUtil.getJSONObjectString2(obj, "huoZhuName");
        if (StringUtil.isNotEmpty(huoZhuName)) {
            transportPlanDto.setHuoZhuName(huoZhuName);
        }

        String qryCreateTime = JsonUtil.getJSONObjectString2(obj, "createTime");
        if (StringUtil.isNotEmpty(qryCreateTime)) {
            String qryCreateTimeMin = qryCreateTime.split(" - ")[0];
            String qryCreateTimeMax = qryCreateTime.split(" - ")[1];
            transportPlanDto.setQryCreateTimeMin(qryCreateTimeMin);
            transportPlanDto.setQryCreateTimeMax(qryCreateTimeMax);
        }

        List<TransportPlanDto> list = iTransportPlanDao.queryTransportPlan(transportPlanDto);
        // 0未开始1运输中2已完成3已延期4已终止
        int sum0 = 0;
        int sum1 = 0;
        int sum2 = 0;
        int sum3 = 0;
        int sum4 = 0;
        JSONArray jsonArray = new JSONArray();
        for (TransportPlanDto transportPlanDto1 : list) {
            if ("0".equals(transportPlanDto1.getTransportState())) {
                sum0 += 1;
            } else if ("1".equals(transportPlanDto1.getTransportState())) {
                sum1 += 1;
            } else if ("2".equals(transportPlanDto1.getTransportState())) {
                sum2 += 1;
            } else if ("4".equals(transportPlanDto1.getTransportState())) {
                sum4 += 1;
            }
            //判断计划结束时间和现在时间对比，现在时间大于计划结束时间说明已延期
            if (DateUtil.compare(new Date(), DateUtil.string2Date(transportPlanDto1.getPlanEndDate())) == 2) {
                //现在的计划是1已开始，就把运输计划时间改成3
                if ("1".equals(transportPlanDto1.getTransportState())) {
                    transportPlanDto = new TransportPlanDto();
                    transportPlanDto.setTransportState("3");
                    transportPlanDto.setId(transportPlanDto1.getId());
                    iTransportPlanDao.updateTransportPlan(transportPlanDto);
                    transportPlanDto1.setTransportState("3");
                }
                if ("3".equals(transportPlanDto1.getTransportState())) {
                    sum3 += 1;
                }
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("planId", transportPlanDto1.getId());
            jsonObject.put("planName", transportPlanDto1.getPlanName());
            jsonObject.put("goodsId", transportPlanDto1.getGoodsId());
            jsonObject.put("goodsName", transportPlanDto1.getGoodsName());
            jsonObject.put("huoZhuId", transportPlanDto1.getHuoZhuId());
            jsonObject.put("huoZhuName", transportPlanDto1.getHuoZhuName());
            jsonObject.put("originalId", transportPlanDto1.getOriginal());
            jsonObject.put("originalName", transportPlanDto1.getOriginalName());
            jsonObject.put("destinationId", transportPlanDto1.getDestination());
            jsonObject.put("destinationName", transportPlanDto1.getDestinationName());
            jsonObject.put("planStartDate", transportPlanDto1.getPlanStartDate());
            jsonObject.put("planEndDate", transportPlanDto1.getPlanEndDate());
            jsonObject.put("planTonnage", transportPlanDto1.getPlanTonnage());
            jsonObject.put("createTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(transportPlanDto1.getCreateTime()));
            jsonObject.put("planHead", transportPlanDto1.getPlanHead());
            jsonObject.put("transportState", transportPlanDto1.getTransportState());
            if ("0".equals(transportPlanDto1.getTransportState())) {
                jsonObject.put("transportStateName", "未开始");
                jsonObject.put("transportStateColor", "#70baff");
            }
            else if ("1".equals(transportPlanDto1.getTransportState())) {
                jsonObject.put("transportStateName", "运输中");
                jsonObject.put("transportStateColor", "#86d37d");
            }
            else if ("2".equals(transportPlanDto1.getTransportState())) {
                jsonObject.put("transportStateName", "已完成");
                jsonObject.put("transportStateColor", "#ff86ac");
            }
            else if ("3".equals(transportPlanDto1.getTransportState())) {
                jsonObject.put("transportStateName", "已延期");
                jsonObject.put("transportStateColor", "#ffbd77");
            }
            else if ("4".equals(transportPlanDto1.getTransportState())) {
                jsonObject.put("transportStateName", "已中止");
                jsonObject.put("transportStateColor", "#aab4be");
            }
            jsonArray.add(jsonObject);
        }
        JSONObject retObj = new JSONObject();
        retObj.put("data", jsonArray);
        retObj.put("count", list.size());
        retObj.put("sum0", sum0);
        retObj.put("sum1", sum1);
        retObj.put("sum2", sum2);
        retObj.put("sum3", sum3);
        retObj.put("sum4", sum4);
        retObj.put("SUCCESS", true);
        logger.info("TransportPlanServiceImpl queryTransportPlan end");
        return retObj;
    }

    /**
     * 查询运输计划详情(运输计划id，公司id)
     *
     * @param request <br/>
     * @return <br/>
     * @throws Exception <br/>
     */
    @Override
    public JSONObject queryTransportPlanDetails(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("TransportPlanServiceImpl queryTransportPlanDetails start obj:{}", obj);
        JSONObject retObj = new JSONObject();
        String planId = JsonUtil.getJSONObjectString(obj, "planId");
        if (StringUtil.isEmpty(planId)) {
            retObj.put("MSG", "运输计划id为空！");
            retObj.put("SUCCESS", false);
            return retObj;
        }
        int companyId = Integer.parseInt((String) request.getSession().getAttribute("SESSION_COMPANY_ID"));
        TransportPlanDto transportPlanDto = new TransportPlanDto();
        transportPlanDto.setCompanyId(companyId);
        transportPlanDto.setId(planId);
        //查询运输计划详情
        transportPlanDto = iTransportPlanDao.queryTransportPlanDetails(transportPlanDto);
        if (null == transportPlanDto) {
            retObj.put("MSG", "查不到运输计划！");
            retObj.put("SUCCESS", false);
            return retObj;
        }
        //查询承运船舶
        List<TransportPlanShipScheduleDto> list = iTransportPlanDao.queryPlanShip(planId);
        double szTonnage = 0.0;
        double ssTonnage = 0.0;

        Long zTotal = 0L;
        Long xTotal = 0L;

        for (TransportPlanShipScheduleDto transportPlanShipScheduleDto : list) {
            String szTonnageStr = transportPlanShipScheduleDto.getSzTonnage();
            String ssTonnageStr = transportPlanShipScheduleDto.getSsTonnage();
            if (StringUtil.isNotEmpty(szTonnageStr)) {
                szTonnage += Double.parseDouble(szTonnageStr);
            }
            if (StringUtil.isNotEmpty(ssTonnageStr)) {
                ssTonnage += Double.parseDouble(ssTonnageStr);
            }
            String startLoadTime = transportPlanShipScheduleDto.getStartLoadTime();
            String endLoadTime = transportPlanShipScheduleDto.getEndLoadTime();
            String endUploadTime = transportPlanShipScheduleDto.getEndUploadTime();
            String startUploadTime = transportPlanShipScheduleDto.getStartUploadTime();

            if (StringUtil.isNotEmpty(startLoadTime) && StringUtil.isNotEmpty(endLoadTime)) {
                Long zDiff = DateUtil.string2Date(endLoadTime).getTime() - DateUtil.string2Date(startLoadTime).getTime();
                zTotal += zDiff;
            }

            if (StringUtil.isNotEmpty(endUploadTime) && StringUtil.isNotEmpty(startUploadTime)) {
                Long xDiff = DateUtil.string2Date(endUploadTime).getTime() - DateUtil.string2Date(startUploadTime).getTime();
                xTotal += xDiff;
            }
        }

        //已完成运输计算相关信息
        JSONObject object = new JSONObject();
        if ("2".equals(transportPlanDto.getTransportState())) {
            String realEndDate = transportPlanDto.getRealEndDate();
            String realStartTime = transportPlanDto.getRealStartTime();
            String planStartDate = transportPlanDto.getPlanStartDate();
//            String planEndDate = transportPlanDto.getPlanEndDate();
            //运输总计用时
            Long total = DateUtil.string2Date(realEndDate).getTime() - DateUtil.string2Date(realStartTime).getTime();
            object.put("totalTime", DateUtil.formatDuring(total));
            if (list.size() > 0) {
                //在航平均时长
                object.put("zhAvg", DateUtil.formatDuring(total / list.size()));
                //装货平均时长
                object.put("zAvg", DateUtil.formatDuring(zTotal / list.size()));
                //卸货平均时长
                object.put("xAvg", DateUtil.formatDuring(xTotal / list.size()));
            }

            //计划执行效率
            Long planTotal = DateUtil.string2Date(realEndDate).getTime() - DateUtil.string2Date(planStartDate).getTime();
            String executeEfficiency = String.format("%.2f",((double) planTotal / total)* 100);
            object.put("executeEfficiency", executeEfficiency + "%");
            //货损率
            String goodsSL = String.format("%.2f",((szTonnage - ssTonnage)/szTonnage)* 1000);
            object.put("goodsSL", goodsSL + "‰");
        }


        object.put("planId", transportPlanDto.getId());
        object.put("planName", transportPlanDto.getPlanName());
        object.put("goodsId", transportPlanDto.getGoodsId());
        object.put("goodsName", transportPlanDto.getGoodsName());
        object.put("huoZhuId", transportPlanDto.getHuoZhuId());
        object.put("huoZhuName", transportPlanDto.getHuoZhuName());
        object.put("huoZhuNamePhone", transportPlanDto.getContactPhone());
        object.put("originalId", transportPlanDto.getOriginal());
        object.put("originalName", transportPlanDto.getOriginalName());
        object.put("destinationId", transportPlanDto.getDestination());
        object.put("destinationName", transportPlanDto.getDestinationName());
        object.put("createTime", DateUtil.date2String(transportPlanDto.getCreateTime(),"yyyy-MM-dd HH:mm:ss"));
        switch (Integer.parseInt(transportPlanDto.getTransportState())) {
            case 0:
                object.put("transportStateName", "未开始");
                break;
            case 1:
                object.put("transportStateName", "运输中");
                break;
            case 2:
                object.put("transportStateName", "已完成");
                break;
            case 3:
                object.put("transportStateName", "已延期");
                break;
            case 4:
                object.put("transportStateName", "已中止");
                break;
            default:
                    object.put("transportStateName", "");
                    break;
        }
        object.put("transportState", transportPlanDto.getTransportState());
        object.put("realStartTime", transportPlanDto.getRealStartTime());
        object.put("realEndDate", transportPlanDto.getRealEndDate());
        object.put("planStartDate", transportPlanDto.getPlanStartDate());
        object.put("planEndDate", transportPlanDto.getPlanEndDate());
        object.put("planTonnage", transportPlanDto.getPlanTonnage());
        object.put("planHead", transportPlanDto.getPlanHead());
        object.put("contactPhone", transportPlanDto.getContactPhone());
        object.put("contactMan", transportPlanDto.getContactMan());
        //实载吨位
        object.put("szTonnage", szTonnage);
        //实收吨位
        object.put("ssTonnage", ssTonnage);
        //计划详情
        retObj.put("data", object);
        //计划船舶详情
        retObj.put("shipList", list);
        retObj.put("SUCCESS", true);
        logger.info("TransportPlanServiceImpl queryTransportPlanDetails end");
        return retObj;

    }

    /**
     * 新增运输计划（计划编号，货主id，货种id，出发地id，到达地id，计划吨位，计划开始时间，计划开始时间范围，计划结束时间，计划结束时间范围）不能为空
     *
     * @param request <br/>
     * @return <br/>
     * @throws Exception <br/>
     */
    @Override
    public JSONObject addTransportPlan(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("TransportPlanServiceImpl addTransportPlan start obj:{}", obj);
        String id = "Ys_" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String planName = JsonUtil.getJSONObjectString(obj, "planName");
        String goodsId = JsonUtil.getJSONObjectString(obj, "goodsId");
        String huoZhuId = JsonUtil.getJSONObjectString(obj, "huoZhuId");
        String original = JsonUtil.getJSONObjectString(obj, "original");
        String destination = JsonUtil.getJSONObjectString(obj, "destination");
        String planTonnage = JsonUtil.getJSONObjectString(obj, "planTonnage");
        String planStartDate = JsonUtil.getJSONObjectString(obj, "planStartDate");
        String planEndDate = JsonUtil.getJSONObjectString(obj, "planEndDate");
        String planHead = JsonUtil.getJSONObjectString2(obj, "planHead");
        String transportState = "0";
        HttpSession httpSession = request.getSession();
        Integer userId = Integer.parseInt((String) httpSession.getAttribute("SESSION_USER_ID"));
        int companyId = Integer.parseInt((String) httpSession.getAttribute("SESSION_COMPANY_ID"));
        if (StringUtil.isEmpty(planName) || StringUtil.isEmpty(goodsId) || StringUtil.isEmpty(huoZhuId)
                || StringUtil.isEmpty(original) || StringUtil.isEmpty(destination) || StringUtil.isEmpty(planTonnage)
                || StringUtil.isEmpty(planStartDate) || StringUtil.isEmpty(planEndDate) || StringUtil.isEmpty(planHead)) {
            JSONObject retObj = new JSONObject();
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "请输入计划信息！");
            return retObj;
        }
        TransportPlanDto transportPlanDto = new TransportPlanDto(id, planName, userId, Integer.parseInt(goodsId), Integer.parseInt(huoZhuId), companyId, original, destination, planTonnage, planStartDate, null, planEndDate, null, transportState, planHead);
        List<TransportPlanDto> list = iTransportPlanDao.queryTransportPlanRepeat(transportPlanDto);
        JSONObject retObj = new JSONObject();
        if (ListUtil.isNotEmpty(list)) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "运输计划名称已存在");
        } else {
            iTransportPlanDao.insertTransportPlan(transportPlanDto);
            retObj.put("SUCCESS", true);
            retObj.put("MSG", "运输计划创建成功");
        }
        logger.info("TransportPlanServiceImpl addTransportPlan end");
        return retObj;
    }

    @Override
    public JSONObject editTransportPlan(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("TransportPlanServiceImpl login start obj:{}", obj);
        String planId = JsonUtil.getJSONObjectString(obj, "planId");
        String planName = JsonUtil.getJSONObjectString2(obj, "planName");
        String goodsId = JsonUtil.getJSONObjectString2(obj, "goodsId");
        String huoZhuId = JsonUtil.getJSONObjectString2(obj, "huoZhuId");
        String original = JsonUtil.getJSONObjectString2(obj, "original");
        String destination = JsonUtil.getJSONObjectString2(obj, "destination");
        String planTonnage = JsonUtil.getJSONObjectString2(obj, "planTonnage");
        String planStartDate = JsonUtil.getJSONObjectString2(obj, "planStartDate");
        String planEndDate = JsonUtil.getJSONObjectString2(obj, "planEndDate");
        String planHead = JsonUtil.getJSONObjectString2(obj, "planHead");
        HttpSession httpSession = request.getSession();
        Integer userId = Integer.parseInt((String) httpSession.getAttribute("SESSION_USER_ID"));
        int companyId = Integer.parseInt((String) httpSession.getAttribute("SESSION_COMPANY_ID"));
        TransportPlanDto transportPlanDto = new TransportPlanDto(planId, planName, userId, Integer.parseInt(goodsId), Integer.parseInt(huoZhuId), companyId, original, destination, planTonnage, planStartDate, null, planEndDate, null, null, planHead);
        List<TransportPlanDto> list = iTransportPlanDao.queryTransportPlanRepeat(transportPlanDto);
        JSONObject retObj = new JSONObject();

        if (checkTransportStateIsOver(planId, retObj)) {
            return retObj;
        }

        if (ListUtil.isNotEmpty(list)) {
            if (list.size() >1) {
                retObj.put("SUCCESS", false);
                retObj.put("MSG", "运输计划名称已存在");
            }
            else {
                if (!list.get(0).getId().equals(planId)) {
                    retObj.put("SUCCESS", false);
                    retObj.put("MSG", "运输计划名称已存在");
                }
                else {
                    iTransportPlanDao.updateTransportPlan(transportPlanDto);
                    retObj.put("SUCCESS", true);
                    retObj.put("MSG", "运输计划修改成功");
                }
            }

        } else {
            iTransportPlanDao.updateTransportPlan(transportPlanDto);
            retObj.put("SUCCESS", true);
            retObj.put("MSG", "运输计划修改成功");
        }
        return retObj;
    }

    @Override
    public JSONObject stopTransportPlan(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("TransportPlanServiceImpl stopTransportPlan start obj:{}", obj);
//        String planIds = JsonUtil.getJSONObjectString(obj, "planIds");
//        String[] planIdsArr = planIds.split(",");
//
//        for (String planId : planIdsArr) {
//            TransportPlanDto transportPlanDto = new TransportPlanDto();
//            transportPlanDto.setId(planId);
//            List<TransportPlanDto> list = iTransportPlanDao.queryTransportPlan(transportPlanDto);
//            transportPlanDto = list.get(0);
//
//            transportPlanDto.setTransportState("4");
//
//            iTransportPlanDao.updateTransportPlan(transportPlanDto);
//        }
        String planId = JsonUtil.getJSONObjectString(obj, "planId");
        JSONObject retObj = new JSONObject();

        if (checkTransportStateIsOver(planId, retObj)) {
            return retObj;
        }

        TransportPlanDto transportPlanDto = new TransportPlanDto();
        transportPlanDto.setId(planId);
        transportPlanDto.setTransportState("4");
        iTransportPlanDao.updateTransportPlan(transportPlanDto);
        retObj.put("SUCCESS", true);
        retObj.put("MSG", "计划已中止");
        return retObj;
    }

    //检查运输状态是否关闭,关闭不能修改
    private Boolean checkTransportStateIsOver(String planId, JSONObject retObj) {
        TransportPlanDto transportPlanDto = new TransportPlanDto();
        transportPlanDto.setId(planId);
        List<TransportPlanDto> list = iTransportPlanDao.queryTransportPlan(transportPlanDto);
        transportPlanDto = list.get(0);
        if ("2".equals(transportPlanDto.getTransportState())) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "计划处于完成状态，不能修改");
            return true;
        }
        return false;
    }

    @Override
    public JSONObject restoreTransportPlan(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("TransportPlanServiceImpl restoreTransportPlan start obj:{}", obj);
        String planId = JsonUtil.getJSONObjectString2(obj, "planId");
        TransportPlanDto transportPlanDto = new TransportPlanDto();
        transportPlanDto.setId(planId);
        List<TransportPlanDto> list = iTransportPlanDao.queryTransportPlan(transportPlanDto);
        transportPlanDto = list.get(0);
        JSONObject retObj = new JSONObject();
        if (!"4".equals(transportPlanDto.getTransportState())) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "计划不处于中止状态，不能恢复");
            return retObj;
        }

        logger.info("TransportPlanServiceImpl deleteTransportPlanShip start obj1:{}", planId);
        iTransportPlanDao.deleteTransportPlanShipByPlanId(planId);
//        logger.info("TransportPlanServiceImpl deleteTransportPlanShip start obj2:{}", transportPlanShipScheduleDto);
//        iTransportPlanDao.deleteSchedule(transportPlanShipScheduleDto);

        //删除 计划 船 航期
        logger.info("TransportPlanServiceImpl deleteTransportPlanShip start obj3:{}", planId);
        iTransportPlanDao.deleteTransportPlanShipScheduleByPlanId(planId);

        transportPlanDto.setTransportState("0");
        transportPlanDto.setRealStartTime("");
        transportPlanDto.setRealEndDate("");
        iTransportPlanDao.updateTransportPlan(transportPlanDto);

        retObj.put("SUCCESS", true);
        retObj.put("MSG", "恢复计划成功");
        return retObj;
    }

    @Override
    public JSONObject addTransportPlanClass(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("TransportPlanServiceImpl addTransportPlanClass start obj:{}", obj);
        String planClassName = JsonUtil.getJSONObjectString(obj, "planClassName");
        JSONObject retObj = new JSONObject();
        if (StringUtil.isEmpty(planClassName)) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "计划分类名称为空！");
            return retObj;
        }
//        int companyId = 4;
        int companyId = Integer.parseInt((String) request.getSession().getAttribute("SESSION_COMPANY_ID"));
        TransportClassDto transportClassDto = new TransportClassDto(planClassName, companyId);
        List<TransportClassDto> list = iTransportPlanDao.selectTransportPlanClass(transportClassDto);
        if (ListUtil.isNotEmpty(list)) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "添加计划分类失败，已经存在该分类");
            return retObj;
        }
        iTransportPlanDao.insertTransportPlanClass(transportClassDto);

        retObj.put("SUCCESS", true);
        retObj.put("MSG", "添加计划分类成功");
        return retObj;
    }

    @Override
    public JSONObject editTransportPlanClass(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("TransportPlanServiceImpl editTransportPlanClass start obj:{}", obj);
        String planClassId = JsonUtil.getJSONObjectString(obj, "planClassId");
        String planClassName = JsonUtil.getJSONObjectString(obj, "planClassName");
        JSONObject retObj = new JSONObject();
        if (StringUtil.isEmpty(planClassId) || StringUtil.isEmpty(planClassName)) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "计划分类信息为空！");
            return retObj;
        }
        int companyId = Integer.parseInt((String) request.getSession().getAttribute("SESSION_COMPANY_ID"));
        TransportClassDto transportClassDto = new TransportClassDto(planClassName, companyId);
        List<TransportClassDto> list = iTransportPlanDao.selectTransportPlanClass(transportClassDto);
        if (ListUtil.isNotEmpty(list)) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "修改计划分类失败，已经存在该分类");
            return retObj;
        }
        transportClassDto.setPlanClassId(Integer.parseInt(planClassId));
        iTransportPlanDao.updateTransportPlanClass(transportClassDto);

        retObj.put("SUCCESS", true);
        retObj.put("MSG", "修改计划分类成功");
        return retObj;
    }

    @Override
    public JSONObject queryTransportPlanClass(HttpServletRequest request) {
        logger.info("TransportPlanServiceImpl addTransportPlanClass start");
//        int companyId = 4;
        int companyId = Integer.parseInt((String) request.getSession().getAttribute("SESSION_COMPANY_ID"));
        TransportClassDto transportClassDto = new TransportClassDto(companyId);
        List<TransportClassDto> list = iTransportPlanDao.selectTransportPlanClass(transportClassDto);
        JSONObject retObj = new JSONObject();
        retObj.put("data", list);
        retObj.put("SUCCESS", true);
        return retObj;
    }

    @Override
    public JSONObject addPlanToTransportPlanClass(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("TransportPlanServiceImpl addPlanToTransportPlanClass start obj:{}", obj);
        String planId = JsonUtil.getJSONObjectString(obj, "planId");
        String planClassId = JsonUtil.getJSONObjectString(obj, "planClassId");
        JSONObject retObj = new JSONObject();
        if (StringUtil.isEmpty(planId) || StringUtil.isEmpty(planClassId)) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "参数为空");
            return retObj;
        }
        TransportClassDto transportClassDto = new TransportClassDto();
        transportClassDto.setPlanClassId(Integer.parseInt(planClassId));
        transportClassDto.setPlanId(planId);
        List<TransportClassDto> list = iTransportPlanDao.selectOPlanClass(transportClassDto);

        if (ListUtil.isNotEmpty(list)) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "添加失败，该计划已经存在该计划分类中！");
            return retObj;
        }
        iTransportPlanDao.insertPlanToTransportPlanClass(transportClassDto);

        retObj.put("SUCCESS", true);
        retObj.put("MSG", "添加计划到计划分类成功");
        return retObj;
    }

    @Override
    public JSONObject deleteTransportPlanClass(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("TransportPlanServiceImpl deleteTransportPlanClass start obj:{}", obj);
        String planClassId = JsonUtil.getJSONObjectString(obj, "planClassId");
        JSONObject retObj = new JSONObject();
        if (StringUtil.isEmpty(planClassId)) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "参数为空");
            return retObj;
        }
        iTransportPlanDao.deleteTransportPlanClass(Integer.parseInt(planClassId));
        iTransportPlanDao.deletePlanToTransportPlanClass(Integer.parseInt(planClassId));
        retObj.put("SUCCESS", true);
        retObj.put("MSG", "计划分类删除成功");
        return retObj;
    }

    @Override
    @Transactional
    public JSONObject addTransportPlanShip(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("TransportPlanServiceImpl addTransportPlanShip start obj:{}", obj);
        JSONObject retObj = new JSONObject();

        String planId = JsonUtil.getJSONObjectString(obj, "planId");
        String push = JsonUtil.getJSONObjectString(obj, "push").toUpperCase();
        String dispatcher = JsonUtil.getJSONObjectString(obj, "dispatcher");
        JSONArray shipList = JsonUtil.getJSONArray(obj, "shipList");

        if (checkTransportStateIsOver(planId, retObj)) {
            return retObj;
        }
//
//        for (int i = 0; i < shipList.size(); i++) {
//            JSONObject object = shipList.getJSONObject(i);
//            String shipId = object.getString("shipId");
//            TransportPlanShipScheduleDto transportPlanShipScheduleDto = new TransportPlanShipScheduleDto(planId, Integer.parseInt(shipId), push, dispatcher);
//            iTransportPlanDao.insertTransportPlanShip(transportPlanShipScheduleDto);
//
//            //添加空的航期
//            iTransportPlanDao.insertSchedule(transportPlanShipScheduleDto);
//
//            //计划 船 航期绑定
//            iTransportPlanDao.insertTransportPlanShipSchedule(transportPlanShipScheduleDto);
//        }
        if (null == shipList || shipList.size() == 0) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "请选择添加船舶");
            return retObj;
        }
        String shipId = shipList.getJSONObject(0).getString("shipId");
        TransportPlanShipScheduleDto transportPlanShipScheduleDto = new TransportPlanShipScheduleDto(planId, Integer.parseInt(shipId), push, dispatcher);
        iTransportPlanDao.insertTransportPlanShip(transportPlanShipScheduleDto);

        //添加空的航期
        iTransportPlanDao.insertSchedule(transportPlanShipScheduleDto);

        //计划 船 航期绑定
        iTransportPlanDao.insertTransportPlanShipSchedule(transportPlanShipScheduleDto);

        if ("Y".equals(push)) {

            //调用扣费逻辑
            String consumeId = JsonUtil.getJSONObjectString(obj, "consumeId");

            JSONObject reqObj = new JSONObject();
            reqObj.put("consumeId", consumeId);
            reqObj.put("shipList", shipList);
            JSONObject ret = iDeductionsServices.deductionsMethod(request, reqObj);
            if (!ret.getBoolean("SUCCESS")) {
                throw new RuntimeException(ret.getString("MSG"));
            }
            updateTuiSongShip();
        }

        retObj.put("SUCCESS", true);
        retObj.put("MSG", "添加计划船舶成功");
        return retObj;
    }

    private void updateTuiSongShip() {
        List<String> mmsiList = iTransportPlanDao.queryPushMMSI();
        StringBuffer sb = new StringBuffer();
        for (String mmsi : mmsiList) {
            sb.append(mmsi).append(",");
        }
        if (sb.length() > 0) {
            JSONObject object = new JSONObject();
            object.put("shipIds", sb.substring(0, sb.length() - 1));
            object = ShipXyAPIUtil.updateShips(object);
            logger.info("addTransportPlanShip push object:{}", object);
        }
    }

    @Override
    public JSONObject deleteTransportPlanShip(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("TransportPlanServiceImpl deleteTransportPlanShip start obj:{}", obj);
        JSONObject retObj = new JSONObject();
        String planId = JsonUtil.getJSONObjectString(obj, "planId");
        TransportPlanDto transportPlanDto = new TransportPlanDto();
        transportPlanDto.setId(planId);
        transportPlanDto = iTransportPlanDao.queryTransportPlanDetails(transportPlanDto);

        if (!"0".equals(transportPlanDto.getTransportState())) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "删除计划船舶失败！只要未开始可以删除");
            return retObj;
        }

        String shipId = JsonUtil.getJSONObjectString(obj, "shipId");
        String sailingScheduleId = JsonUtil.getJSONObjectString(obj, "sailingScheduleId");
        TransportPlanShipScheduleDto transportPlanShipScheduleDto = new TransportPlanShipScheduleDto(planId, Integer.parseInt(shipId));
        transportPlanShipScheduleDto.setSailingScheduleId(Integer.parseInt(sailingScheduleId));
        logger.info("TransportPlanServiceImpl deleteTransportPlanShip start obj1:{}", transportPlanShipScheduleDto);
        iTransportPlanDao.deleteTransportPlanShip(transportPlanShipScheduleDto);
        logger.info("TransportPlanServiceImpl deleteTransportPlanShip start obj2:{}", transportPlanShipScheduleDto);
        iTransportPlanDao.deleteSchedule(transportPlanShipScheduleDto);

        //删除 计划 船 航期
        logger.info("TransportPlanServiceImpl deleteTransportPlanShip start obj3:{}", transportPlanShipScheduleDto);
        iTransportPlanDao.deleteTransportPlanShipSchedule(transportPlanShipScheduleDto);

        retObj.put("SUCCESS", true);
        retObj.put("MSG", "删除计划船舶成功");
        return retObj;
    }

    @Override
    @Transactional
    public JSONObject editSchedule(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("TransportPlanServiceImpl editSchedule start obj:{}", obj);
        String sailingScheduleId = JsonUtil.getJSONObjectString2(obj, "sailingScheduleId");
        String planId = JsonUtil.getJSONObjectString2(obj, "planId");
        String shipId = JsonUtil.getJSONObjectString2(obj, "shipId");
        JSONObject retObj = new JSONObject();

        if (StringUtil.isEmpty(sailingScheduleId) || StringUtil.isEmpty(planId) || StringUtil.isEmpty(shipId)) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "传入参数为空");
            return retObj;
        }

        if (checkTransportStateIsOver(planId, retObj)) {
            return retObj;
        }
        String arrivedOriginalTime = JsonUtil.getJSONObjectString2(obj, "arrivedOriginalTime");
        String endUploadTime = JsonUtil.getJSONObjectString2(obj, "endUploadTime");

        TransportPlanShipScheduleDto transportPlanShipScheduleDto = new TransportPlanShipScheduleDto();
        transportPlanShipScheduleDto.setSailingScheduleId(Integer.parseInt(sailingScheduleId));
        transportPlanShipScheduleDto.setPlanId(planId);
        transportPlanShipScheduleDto.setShipId(Integer.parseInt(shipId));
        transportPlanShipScheduleDto = iTransportPlanDao.querySchedule(transportPlanShipScheduleDto);
        if (null == transportPlanShipScheduleDto) {
            retObj.put("SUCCESS", false);
            retObj.put("MSG", "没有该航期");
            return retObj;
        }
        retObj = checkScheduleInput(obj, transportPlanShipScheduleDto);
        if (!retObj.getBoolean("SUCCESS")) {
            return retObj;
        }

        TransportPlanDto transportPlanDto = new TransportPlanDto();
        transportPlanDto.setId(planId);
        editRealStartTime(transportPlanDto, arrivedOriginalTime, planId, shipId);
        editRealEndTime(transportPlanDto, endUploadTime, planId, shipId);

        iTransportPlanDao.updateSchedule(transportPlanShipScheduleDto);
        updateTuiSongShip();

        retObj.put("SUCCESS", true);
        retObj.put("MSG", "修改航期成功");
        return retObj;
    }

    //修改真实运输开始时间
    private void editRealStartTime(TransportPlanDto transportPlanDto, String arrivedOriginalTime, String planId, String shipId) {
        if (StringUtil.isNotEmpty(arrivedOriginalTime)) {
            transportPlanDto = iTransportPlanDao.queryTransportPlanDetails(transportPlanDto);
            if (StringUtil.isEmpty(transportPlanDto.getRealStartTime())) {
                transportPlanDto.setRealStartTime(arrivedOriginalTime);
                transportPlanDto.setTransportState("1");
                iTransportPlanDao.updateTransportPlan(transportPlanDto);
            } else {
                List<TransportPlanShipScheduleDto> list = iTransportPlanDao.queryPlanShip(planId);
                String minArrivedOriginalTime = arrivedOriginalTime;
                for (TransportPlanShipScheduleDto transportPlanShipScheduleDto1 : list) {
                    if (transportPlanShipScheduleDto1.getShipId() != Integer.parseInt(shipId)) {
                        if (StringUtil.isNotEmpty(transportPlanShipScheduleDto1.getArrivedOriginalTime())) {
                            if (DateUtil.compare(DateUtil.string2Date(transportPlanShipScheduleDto1.getArrivedOriginalTime()), DateUtil.string2Date(minArrivedOriginalTime)) == 0) {
                                minArrivedOriginalTime = transportPlanShipScheduleDto1.getArrivedOriginalTime();
                            }
                        }
                    }
                }
                transportPlanDto.setRealStartTime(minArrivedOriginalTime);
                transportPlanDto.setTransportState("1");
                iTransportPlanDao.updateTransportPlan(transportPlanDto);
            }
        }
    }

    //修改真实运输结束时间
    private void editRealEndTime(TransportPlanDto transportPlanDto, String endUploadTime, String planId, String shipId) {
        if (StringUtil.isNotEmpty(endUploadTime)) {
            List<TransportPlanShipScheduleDto> list = iTransportPlanDao.queryPlanShip(planId);
            int size = 0;
            String maxEndUploadTime = endUploadTime;
            for (int i = 0; i < list.size(); i++) {
                TransportPlanShipScheduleDto transportPlanShipScheduleDto1 = list.get(i);
                if (transportPlanShipScheduleDto1.getShipId() != Integer.parseInt(shipId)) {
                    if (StringUtil.isEmpty(transportPlanShipScheduleDto1.getEndUploadTime())) {
                        break;
                    }
                    if (DateUtil.compare(DateUtil.string2Date(transportPlanShipScheduleDto1.getEndUploadTime()), DateUtil.string2Date(maxEndUploadTime)) == 2) {
                        maxEndUploadTime = transportPlanShipScheduleDto1.getEndUploadTime();
                    }

                }
                size += 1;
                if (size == list.size()) {
                    transportPlanDto.setRealEndDate(maxEndUploadTime);
                    transportPlanDto.setTransportState("2");
                    iTransportPlanDao.updateTransportPlan(transportPlanDto);
                    TransportPlanShipScheduleDto transportPlanShipScheduleDto2 = new TransportPlanShipScheduleDto();
                    transportPlanShipScheduleDto2.setPlanId(planId);
                    transportPlanShipScheduleDto2.setShipId(Integer.parseInt(shipId));
                    iTransportPlanDao.updateTransportPlanShip(transportPlanShipScheduleDto2);
                }
            }
        }
    }

    private JSONObject checkScheduleInput(JSONObject obj, TransportPlanShipScheduleDto transportPlanShipScheduleDto) {
        String arrivedOriginalTime = JsonUtil.getJSONObjectString2(obj, "arrivedOriginalTime");
        String startLoadTime = JsonUtil.getJSONObjectString2(obj, "startLoadTime");
        String endLoadTime = JsonUtil.getJSONObjectString2(obj, "endLoadTime");
        String arrivedDestinationTime = JsonUtil.getJSONObjectString2(obj, "arrivedDestinationTime");
        String startUploadTime = JsonUtil.getJSONObjectString2(obj, "startUploadTime");
        String endUploadTime = JsonUtil.getJSONObjectString2(obj, "endUploadTime");
        String szTonnage = JsonUtil.getJSONObjectString2(obj, "szTonnage");
        String ssTonnage = JsonUtil.getJSONObjectString2(obj, "ssTonnage");
        JSONObject retObj = new JSONObject();
        if (StringUtil.isEmpty(arrivedOriginalTime) && StringUtil.isEmpty(startLoadTime) && StringUtil.isEmpty(endLoadTime)
                && StringUtil.isEmpty(arrivedDestinationTime) && StringUtil.isEmpty(startUploadTime)
                && StringUtil.isEmpty(endUploadTime) && StringUtil.isEmpty(szTonnage) && StringUtil.isEmpty(ssTonnage)) {

            retObj.put("SUCCESS", false);
            retObj.put("MSG", "修改航期失败，数据为空");
            return retObj;
        }

        if (StringUtil.isNotEmpty(szTonnage)) {
            transportPlanShipScheduleDto.setSzTonnage(szTonnage);
        }
        if (StringUtil.isNotEmpty(ssTonnage)) {
            transportPlanShipScheduleDto.setSsTonnage(ssTonnage);
        }

        if (StringUtil.isNotEmpty(arrivedOriginalTime)) {
            transportPlanShipScheduleDto.setArrivedOriginalTime(arrivedOriginalTime);
        }

        retObj = checkScheduleInputStartLoadTime(startLoadTime, transportPlanShipScheduleDto);
        if (!retObj.getBoolean("SUCCESS")) {
            return retObj;
        }

        retObj = checkScheduleInputEndLoadTime(endLoadTime, transportPlanShipScheduleDto);
        if (!retObj.getBoolean("SUCCESS")) {
            return retObj;
        }

        retObj = checkScheduleInputArrivedDestinationTime(arrivedDestinationTime, transportPlanShipScheduleDto);
        if (!retObj.getBoolean("SUCCESS")) {
            return retObj;
        }

        retObj = checkScheduleInputStartUploadTime(startUploadTime, transportPlanShipScheduleDto);
        if (!retObj.getBoolean("SUCCESS")) {
            return retObj;
        }

        retObj = checkScheduleInputEndUploadTime(endUploadTime, transportPlanShipScheduleDto);
        if (!retObj.getBoolean("SUCCESS")) {
            return retObj;
        }

        retObj.put("SUCCESS", true);
        return retObj;
    }

    private JSONObject checkScheduleInputStartLoadTime(String startLoadTime, TransportPlanShipScheduleDto transportPlanShipScheduleDto) {
        JSONObject retObj = new JSONObject();
        if (StringUtil.isNotEmpty(startLoadTime)) {
            String arrivedOriginalTimeDto = transportPlanShipScheduleDto.getArrivedOriginalTime();
            if (StringUtil.isEmpty(arrivedOriginalTimeDto)) {
                retObj.put("SUCCESS", false);
                retObj.put("MSG", "修改航期失败，抵达装货地时间为空");
                return retObj;
            }
            if (DateUtil.compareToTime(arrivedOriginalTimeDto, startLoadTime) == 0) {
                transportPlanShipScheduleDto.setStartLoadTime(startLoadTime);
            } else {
                retObj.put("SUCCESS", false);
                retObj.put("MSG", "修改航期失败，开始装货时间小于抵达装货地时间");
                return retObj;
            }
        }

        retObj.put("SUCCESS", true);
        return retObj;
    }

    private JSONObject checkScheduleInputEndLoadTime(String endLoadTime, TransportPlanShipScheduleDto transportPlanShipScheduleDto) {
        JSONObject retObj = new JSONObject();
        if (StringUtil.isNotEmpty(endLoadTime)) {
            String startLoadTimeDto = transportPlanShipScheduleDto.getStartLoadTime();
            if (StringUtil.isEmpty(startLoadTimeDto)) {
                retObj.put("SUCCESS", false);
                retObj.put("MSG", "修改航期失败，开始装货时间为空");
                return retObj;
            }
            if (DateUtil.compareToTime(startLoadTimeDto, endLoadTime) == 0) {
                transportPlanShipScheduleDto.setEndLoadTime(endLoadTime);
            } else {
                retObj.put("SUCCESS", false);
                retObj.put("MSG", "修改航期失败，结束装货时间小于开始装货时间");
                return retObj;
            }
        }

        retObj.put("SUCCESS", true);
        return retObj;
    }

    private JSONObject checkScheduleInputArrivedDestinationTime(String arrivedDestinationTime, TransportPlanShipScheduleDto transportPlanShipScheduleDto) {
        JSONObject retObj = new JSONObject();
        if (StringUtil.isNotEmpty(arrivedDestinationTime)) {
            String endLoadTimeDto = transportPlanShipScheduleDto.getEndLoadTime();
            if (StringUtil.isEmpty(endLoadTimeDto)) {
                retObj.put("SUCCESS", false);
                retObj.put("MSG", "修改航期失败，结束装货时间为空");
                return retObj;
            }

            String szTonnage = transportPlanShipScheduleDto.getSzTonnage();
            if (StringUtil.isEmpty(szTonnage)) {
                retObj.put("SUCCESS", false);
                retObj.put("MSG", "修改航期失败，实装吨位为空");
                return retObj;
            }

            if (DateUtil.compareToTime(endLoadTimeDto, arrivedDestinationTime) == 0) {
                transportPlanShipScheduleDto.setArrivedDestinationTime(arrivedDestinationTime);
            } else {
                retObj.put("SUCCESS", false);
                retObj.put("MSG", "修改航期失败，抵达目的地时间小于结束装货时间");
                return retObj;
            }
        }

        retObj.put("SUCCESS", true);
        return retObj;
    }

    private JSONObject checkScheduleInputStartUploadTime(String startUploadTime, TransportPlanShipScheduleDto transportPlanShipScheduleDto) {
        JSONObject retObj = new JSONObject();
        if (StringUtil.isNotEmpty(startUploadTime)) {
            String arrivedDestinationTimeDto = transportPlanShipScheduleDto.getArrivedDestinationTime();
            if (StringUtil.isEmpty(arrivedDestinationTimeDto)) {
                retObj.put("SUCCESS", false);
                retObj.put("MSG", "修改航期失败，抵达目的地时间为空");
                return retObj;
            }
            if (DateUtil.compareToTime(arrivedDestinationTimeDto, startUploadTime) == 0) {
                transportPlanShipScheduleDto.setStartUploadTime(startUploadTime);
            } else {
                retObj.put("SUCCESS", false);
                retObj.put("MSG", "修改航期失败，开始卸货时间小于抵达目的地时间");
                return retObj;
            }
        }

        retObj.put("SUCCESS", true);
        return retObj;
    }

    private JSONObject checkScheduleInputEndUploadTime(String endUploadTime, TransportPlanShipScheduleDto transportPlanShipScheduleDto) {
        JSONObject retObj = new JSONObject();
        if (StringUtil.isNotEmpty(endUploadTime)) {
            String startUploadTimeDto = transportPlanShipScheduleDto.getArrivedDestinationTime();
            if (StringUtil.isEmpty(startUploadTimeDto)) {
                retObj.put("SUCCESS", false);
                retObj.put("MSG", "修改航期失败，开始卸货时间为空");
                return retObj;
            }

            String ssTonnage = transportPlanShipScheduleDto.getSsTonnage();
            if (StringUtil.isEmpty(ssTonnage)) {
                retObj.put("SUCCESS", false);
                retObj.put("MSG", "修改航期失败，实收吨位为空");
                return retObj;
            }

            if (DateUtil.compareToTime(startUploadTimeDto, endUploadTime) == 0) {
                transportPlanShipScheduleDto.setEndUploadTime(endUploadTime);
            } else {
                retObj.put("SUCCESS", false);
                retObj.put("MSG", "修改航期失败，已卸完时间小于开始卸货时间");
                return retObj;
            }
        }

        retObj.put("SUCCESS", true);
        return retObj;
    }


    @Override
    public JSONObject queryPlanShip(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("TransportPlanServiceImpl queryPlanShip start obj:{}", obj);
        String planId = JsonUtil.getJSONObjectString(obj, "planId");
        String state = JsonUtil.getJSONObjectString(obj, "state");
        List<TransportPlanShipScheduleDto> list = iTransportPlanDao.queryPlanShip(planId);

        //逆解析
        int length = list.size();
        StringBuffer sb = new StringBuffer();
        List<TransportPlanShipScheduleDto> transportPlanShipScheduleDtoList1 = new ArrayList<>();
        for(int i = 0; i < length; i++) {
            TransportPlanShipScheduleDto transportPlanShipScheduleDto = list.get(i);
            if (StringUtil.isEmpty(transportPlanShipScheduleDto.getCityName())) {
                if (i%20 == 0 && i != 0) {
                    getCityName(sb, null , null,list,transportPlanShipScheduleDtoList1,"N");
                    sb =  new StringBuffer();
                    transportPlanShipScheduleDtoList1 = new ArrayList<>();
                }
                if (StringUtil.isNotEmpty(transportPlanShipScheduleDto.getGLon()) && StringUtil.isNotEmpty(transportPlanShipScheduleDto.getGLat())) {
                    sb.append(transportPlanShipScheduleDto.getLon()).append(",").append(transportPlanShipScheduleDto.getLat()).append("|");
                    transportPlanShipScheduleDtoList1.add(transportPlanShipScheduleDto);
                }
            }
        }
        if (sb.length() > 0) {
            getCityName(sb, null , null,list,transportPlanShipScheduleDtoList1,"N");
        }

        JSONObject retObj = new JSONObject();
        JSONArray allList = new JSONArray();
        JSONArray endList = new JSONArray();
        JSONArray unEndList = new JSONArray();
        for (TransportPlanShipScheduleDto transportPlanShipScheduleDto : list) {
            if (StringUtil.isNotEmpty(transportPlanShipScheduleDto.getEndUploadTime())) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("data", transportPlanShipScheduleDto);
                jsonObject.put("lastUpdate", transportPlanShipScheduleDto.getEndUploadTime());
                jsonObject.put("lastLabel", "已卸空");
                jsonObject.put("process", "100%");
                jsonObject.put("processName", "已卸货");
                endList.add(jsonObject);
                allList.add(jsonObject);
            } else {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("data", transportPlanShipScheduleDto);
                if (StringUtil.isNotEmpty(transportPlanShipScheduleDto.getStartUploadTime())) {
                    jsonObject.put("lastUpdate", transportPlanShipScheduleDto.getStartUploadTime());
                    jsonObject.put("lastLabel", "开始卸货");
                    jsonObject.put("process", "82%");
                    jsonObject.put("processName", "进行中");
                } else if (StringUtil.isNotEmpty(transportPlanShipScheduleDto.getArrivedDestinationTime())) {
                    jsonObject.put("lastUpdate", transportPlanShipScheduleDto.getArrivedDestinationTime());
                    jsonObject.put("lastLabel", "抵达卸货地");
                    jsonObject.put("process", "66%");
                    jsonObject.put("processName", "进行中");
                } else if (StringUtil.isNotEmpty(transportPlanShipScheduleDto.getEndLoadTime())) {
                    jsonObject.put("lastUpdate", transportPlanShipScheduleDto.getEndLoadTime());
                    jsonObject.put("lastLabel", "已装完");
                    jsonObject.put("process", "50%");
                    jsonObject.put("processName", "进行中");
                } else if (StringUtil.isNotEmpty(transportPlanShipScheduleDto.getStartLoadTime())) {
                    jsonObject.put("lastUpdate", transportPlanShipScheduleDto.getStartLoadTime());
                    jsonObject.put("lastLabel", "开始装货");
                    jsonObject.put("process", "32%");
                    jsonObject.put("processName", "进行中");
                } else if (StringUtil.isNotEmpty(transportPlanShipScheduleDto.getArrivedOriginalTime())) {
                    jsonObject.put("lastUpdate", transportPlanShipScheduleDto.getArrivedOriginalTime());
                    jsonObject.put("lastLabel", "抵达装货地");
                    jsonObject.put("process", "16%");
                    jsonObject.put("processName", "进行中");
                } else {
                    jsonObject.put("lastUpdate", "");
                    jsonObject.put("lastLabel", "");
                    jsonObject.put("process", "0%");
                    jsonObject.put("processName", "未开始");
                }
                unEndList.add(jsonObject);
                allList.add(jsonObject);
            }
        }
        if ("1".equals(state)) {
            retObj.put("data", unEndList);
        } else if ("2".equals(state)) {
            retObj.put("data", endList);
        }
        else {
            retObj.put("data", allList);
        }

        retObj.put("SUCCESS", true);
        return retObj;
    }

    @Override
    public JSONObject queryPlanShipShipSchedule(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("TransportPlanServiceImpl queryPlanShipShipSchedule start obj:{}", obj);
        String planId = JsonUtil.getJSONObjectString(obj, "planId");
        String shipId = JsonUtil.getJSONObjectString(obj, "shipId");
        String sailingScheduleId = JsonUtil.getJSONObjectString(obj, "sailingScheduleId");
        List<TransportPlanShipScheduleDto> list;
        TransportPlanShipScheduleDto transportPlanShipScheduleDto;
        if (StringUtil.isNotEmpty(sailingScheduleId)) {
            transportPlanShipScheduleDto = new TransportPlanShipScheduleDto(Integer.parseInt(sailingScheduleId));
        }
        else {
            transportPlanShipScheduleDto = new TransportPlanShipScheduleDto(planId, Integer.parseInt(shipId));
        }

        list = iTransportPlanDao.queryPlanShipShipSchedule(transportPlanShipScheduleDto);

        JSONObject retObj = new JSONObject();
        retObj.put("data", list.get(0));
        retObj.put("SUCCESS", true);
        return retObj;
    }

    private void getCityName(StringBuffer sb, List<ShipInfoDto> shipInfoDtoList, List<ShipInfoDto> shipInfoDtoList1,
                             List<TransportPlanShipScheduleDto> transportPlanShipScheduleDtoList, List<TransportPlanShipScheduleDto> transportPlanShipScheduleDtoList1,String flag) {
        String zb;
        try {
            zb = URLEncoder.encode(sb.substring(0, sb.length() -1), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return;
        }
        String reqUrl = URL.replaceAll("ZB", zb).replaceAll("PL","true");
        JSONObject object = HttpUtil.get(reqUrl);

        String status = object.getString("status");
        if ("1".equals(status)) {
            JSONArray jsonArray = object.getJSONArray("regeocodes");
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject1 = (JSONObject) jsonArray.get(i);
                JSONObject addressComponent = jsonObject1.getJSONObject("addressComponent");
                String city = addressComponent.getString("city");
                if ("[]".equals(city)) {
                    city = addressComponent.getString("province");
                }
                String district = addressComponent.getString("district");
                if ("Y".equals(flag)) {
                    ShipInfoDto shipInfoDto = shipInfoDtoList1.get(i);
                    for (ShipInfoDto shipInfoDto2 : shipInfoDtoList) {
                        if (shipInfoDto.getMmsi().equals(shipInfoDto2.getMmsi())) {
                            shipInfoDto2.setCityName(city+district);
                            iShipDao.updateCityName(shipInfoDto2);
                            break;
                        }
                    }
                }
                else {
                    TransportPlanShipScheduleDto transportPlanShipScheduleDto = transportPlanShipScheduleDtoList1.get(i);
                    for (TransportPlanShipScheduleDto transportPlanShipScheduleDto2 : transportPlanShipScheduleDtoList) {
                        if (transportPlanShipScheduleDto.getMmsi().equals(transportPlanShipScheduleDto2.getMmsi())) {
                            transportPlanShipScheduleDto2.setCityName(city+district);
                            ShipInfoDto shipInfoDto = new ShipInfoDto();
                            shipInfoDto.setMmsi(transportPlanShipScheduleDto.getMmsi());
                            shipInfoDto.setCityName(city+district);
                            iShipDao.updateCityName(shipInfoDto);
                            break;
                        }
                    }
                }
            }
        }
    }

    @Override
    public JSONObject queryAvShip(HttpServletRequest request) throws Exception {
        JSONObject obj = JsonUtil.getJSONObject(request);
        logger.info("TransportPlanServiceImpl queryAvShip start obj:{}", obj);
        String shipName = JsonUtil.getJSONObjectString2(obj, "shipName");
        String planId = JsonUtil.getJSONObjectString2(obj, "planId");
        String page = JsonUtil.getJSONObjectString2(obj, "page");
        String limit = JsonUtil.getJSONObjectString2(obj, "limit");
        int companyId = Integer.parseInt((String) request.getSession().getAttribute("SESSION_COMPANY_ID"));
        ParamDto param = new ParamDto();
        param.setCompanyId(companyId);
        JSONObject retObj = new JSONObject();
        param.setShipName(shipName);
        param.setPlanId(planId);
        PageHelper.startPage(Integer.parseInt(page),Integer.parseInt(limit));
        param.setEndTime(new Timestamp((new Date()).getTime()));
        List<ShipInfoDto> shipInfoDtoList = iShipDao.queryAvShip(param);

        if (ListUtil.isEmpty(shipInfoDtoList)) {
            List<TransportPlanShipScheduleDto> list = iTransportPlanDao.queryPlanShip(planId);
            if (StringUtil.isNotEmpty(shipName)) {
                if (ListUtil.isNotEmpty(list)) {
                    for (TransportPlanShipScheduleDto transportPlanShipScheduleDto : list) {
                        if (shipName.equals(transportPlanShipScheduleDto.getShipName())) {
                            retObj.put("MSG", "当前船舶已添加到该运力");
                            retObj.put("FLAG", 1);
                            retObj.put("SUCCESS", false);
                            return retObj;
                        }
                    }
                }
                retObj.put("MSG", "当前搜索的船舶尚未收录，您可以至定制运力池付费添加船舶并长期监测");
                retObj.put("FLAG", 0);
                retObj.put("SUCCESS", false);
                return retObj;
            }
        }

        //逆解析
        int length = shipInfoDtoList.size();
        StringBuffer sb = new StringBuffer();
        List<ShipInfoDto> shipInfoDtoList1 = new ArrayList<>();
        for(int i = 0; i < length; i++) {
            ShipInfoDto shipInfoDto = shipInfoDtoList.get(i);
            if (StringUtil.isEmpty(shipInfoDto.getCityName())) {
                if (i%20 == 0 && i != 0) {
                    getCityName(sb, shipInfoDtoList, shipInfoDtoList1,null,null,"Y");
                    sb =  new StringBuffer();
                    shipInfoDtoList1 = new ArrayList<>();
                }
                if (StringUtil.isNotEmpty(shipInfoDto.getGLon()) && StringUtil.isNotEmpty(shipInfoDto.getGLat())) {
                    sb.append(shipInfoDto.getLon()).append(",").append(shipInfoDto.getLat()).append("|");
                    shipInfoDtoList1.add(shipInfoDto);
                }
            }
        }
        if (sb.length() > 0) {
            getCityName(sb, shipInfoDtoList, shipInfoDtoList1,null,null,"Y");
        }

        JSONArray retArr = new JSONArray();
        for (ShipInfoDto shipInfoDto : shipInfoDtoList) {
            JSONObject jo = new JSONObject();
            jo.put("shipId", shipInfoDto.getShipId());
            jo.put("shipName", shipInfoDto.getShipName());
            jo.put("tonnage", shipInfoDto.getTonnage() + "吨");
            jo.put("phoneNum", shipInfoDto.getPhoneNum());
            jo.put("mmsi", shipInfoDto.getMmsi());
            jo.put("GLon", shipInfoDto.getGLon());
            jo.put("GLat", shipInfoDto.getGLat());
            jo.put("destStd", shipInfoDto.getDestStd());
            jo.put("etaStd", shipInfoDto.getEtaStd());
            jo.put("cityName", shipInfoDto.getCityName());
            retArr.add(jo);
        }

        retObj.put("shipList", retArr);
        PageInfo pageInfo = new PageInfo(shipInfoDtoList);
        retObj.put("pageInfo",pageInfo);
        retObj.put("SUCCESS", true);
        retObj.put("FLAG", 2);
        return retObj;


//        String dunWei = JsonUtil.getJSONObjectString2(obj,"dunWei");
//        String chuFaDi = JsonUtil.getJSONObjectString2(obj,"chuFaDi");
//        String shipName = JsonUtil.getJSONObjectString2(obj,"shipName");
//        String planId = JsonUtil.getJSONObjectString2(obj,"planId");
//        ParamDto param = new ParamDto();
//        if (StringUtil.isNotEmpty(dunWei)) {
//            String[] dunWeiArr = dunWei.split("-");
//            param.setMinTonnage(Double.parseDouble(dunWeiArr[0]));
//            param.setMaxTonnage(Double.parseDouble(dunWeiArr[1]));
//        }
//
////        int companyId = 4;
//        int companyId = Integer.parseInt((String) request.getSession().getAttribute("SESSION_COMPANY_ID"));
//        param.setCompanyId(companyId);
//        if (StringUtil.isNotEmpty(shipName)) {
//            param.setShipName(shipName);
//        }
//
////        param.setPlanId("Ys_20181102104240");
//        param.setPlanId(planId);
//        List<ShipInfoDto> shipInfoDtoList = iShipDao.queryZYShip(param);
//        JSONArray areaArr = null;
//        JSONArray retArr = new JSONArray();
//        if (StringUtil.isNotEmpty(chuFaDi)) {
//            JSONObject qryAreaObj = new JSONObject();
//            RegionDto regionDto = new RegionDto();
//            regionDto.setRegionName(chuFaDi);
//            qryAreaObj.put("jinWei", iShipDao.queryRegion(regionDto).get(0).getRegionLatLon());
//            JSONObject areaObj = ShipXyAPIUtil.getAreaShip(qryAreaObj);
//            areaArr = areaObj.getJSONArray("data");
//            for (ShipInfoDto shipInfoDto : shipInfoDtoList) {
//                for (int i = 0; i < areaArr.size(); i++) {
//                    JSONObject areaObj1 = (JSONObject) areaArr.get(i);
//                    if (shipInfoDto.getMmsi().equals(areaObj1.getString("mmsi"))) {
//                        JSONObject jo = new JSONObject();
//                        jo.put("shipId",shipInfoDto.getShipId());
//                        jo.put("shipName",shipInfoDto.getShipName());
//                        jo.put("tonnage",shipInfoDto.getTonnage() + "吨");
////                        jo.put("phoneNum",shipInfoDto.getPhoneNum());
////                        String lon = String.valueOf(areaObj1.getLong("lon")/1000000.0);
////                        String lat = String.valueOf(areaObj1.getLong("lat")/1000000.0);
////                        jo.put("lon", lon);
////                        jo.put("lat", lat);
////                        jo.put("dest", areaObj1.getString("dest"));
////                        jo.put("etaStd", areaObj1.getString("eta_std"));
//                        jo.put("mmsi",shipInfoDto.getMmsi());
//                        retArr.add(jo);
//                    }
//                }
//            }
//        }
//        else {
//            for (ShipInfoDto shipInfoDto : shipInfoDtoList) {
//                JSONObject jo = new JSONObject();
//                jo.put("shipId",shipInfoDto.getShipId());
//                jo.put("shipName",shipInfoDto.getShipName());
//                jo.put("tonnage",shipInfoDto.getTonnage() + "吨");
//                jo.put("phoneNum",shipInfoDto.getPhoneNum());
//                jo.put("mmsi",shipInfoDto.getMmsi());
//                retArr.add(jo);
//            }
//            /*StringBuffer sb = new StringBuffer();
//            for (ShipInfoDto shipInfoDto : shipInfoDtoList) {
//                sb.append(shipInfoDto.getMmsi()).append(",");
//            }
//            if (sb.length() > 0) {
//                JSONObject qryManyObj = new JSONObject();
//                qryManyObj.put("shipIds", sb.substring(0,sb.length() - 1));
//                JSONObject manyObj = ShipXyAPIUtil.getManyShip(qryManyObj);
//                areaArr = manyObj.getJSONArray("data");
//            }*/
//        }
//
//        JSONObject retObj = new JSONObject();
//        retObj.put("shipList", retArr);
//        retObj.put("SUCCESS", true);
//        return retObj;
    }

    @Override
    public void exportTransportExcel(HttpServletRequest request, HttpServletResponse response, JSONObject obj) throws IOException {

        OutputStream os = null;
        try {
            String planId = null;
            String transportState = null;
            if (null != obj) {
                planId = JsonUtil.getJSONObjectString2(obj,"planId");
                transportState = JsonUtil.getJSONObjectString2(obj,"transportState");
            }
            int companyId = Integer.parseInt((String) request.getSession().getAttribute("SESSION_COMPANY_ID"));
            ExportTransportPlanDto qryDto = new ExportTransportPlanDto();
            qryDto.setPlanId(planId);
            qryDto.setTransportState(transportState);
            qryDto.setCompanyId(companyId);
            List<ExportTransportPlanDto> list = iTransportPlanDao.queryExportTransportInfo(qryDto);

            List<Object> dataList = new ArrayList<>();
            for (ExportTransportPlanDto transportPlanDto : list) {
                if ("0".equals(transportPlanDto.getTransportState())) {
                    transportPlanDto.setTransportState("未开始");
                } else if ("1".equals(transportPlanDto.getTransportState())) {
                    transportPlanDto.setTransportState("运输中");
                } else if ("2".equals(transportPlanDto.getTransportState())) {
                    transportPlanDto.setTransportState("已完成");
                } else if ("3".equals(transportPlanDto.getTransportState())) {
                    transportPlanDto.setTransportState("已延期");
                } else if ("4".equals(transportPlanDto.getTransportState())) {
                    transportPlanDto.setTransportState("已终止");
                }
                ExportTransportPlanDto qryDto1 = new ExportTransportPlanDto();
                qryDto1.setPlanId(transportPlanDto.getPlanId());
                List<ExportTransportPlanDto> list1 = iTransportPlanDao.queryExportTransportInfo1(qryDto1);
                if (ListUtil.isNotEmpty(list1)) {
                    for (ExportTransportPlanDto exportTransportPlanDto : list1) {
                        ExportTransportPlanDto transportPlanDto1 = (ExportTransportPlanDto) transportPlanDto.clone();
                        transportPlanDto1.setShipName(exportTransportPlanDto.getShipName());
                        transportPlanDto1.setShipOwnerName(exportTransportPlanDto.getShipOwnerName());
                        transportPlanDto1.setPhoneNum(exportTransportPlanDto.getPhoneNum());
                        transportPlanDto1.setArrivedOriginalTime(exportTransportPlanDto.getArrivedDestinationTime());
                        transportPlanDto1.setStartLoadTime(exportTransportPlanDto.getStartLoadTime());
                        transportPlanDto1.setSzTonnage(exportTransportPlanDto.getSzTonnage());
                        transportPlanDto1.setEndLoadTime(exportTransportPlanDto.getEndLoadTime());
                        transportPlanDto1.setArrivedDestinationTime(exportTransportPlanDto.getArrivedDestinationTime());
                        transportPlanDto1.setStartUploadTime(exportTransportPlanDto.getStartUploadTime());
                        transportPlanDto1.setEndUploadTime(exportTransportPlanDto.getEndUploadTime());
                        transportPlanDto1.setSsTonnage(exportTransportPlanDto.getSsTonnage());
                        transportPlanDto1.setDispatcher(exportTransportPlanDto.getDispatcher());
                        if (null != exportTransportPlanDto.getZqUnix()) {
                            transportPlanDto1.setZq(DateUtil.formatDuring(exportTransportPlanDto.getZqUnix() * 1000));
                        }
                        dataList.add(transportPlanDto1);
                    }
                }
                else {
                    dataList.add(transportPlanDto);
                }
            }
            HSSFWorkbook wb = new HSSFWorkbook();
            HSSFSheet sheet = wb.createSheet("transport");

            IDownloadHandler transportDownloadHandler = new TransportDownloadHandler();
            transportDownloadHandler.dealReportHeader(wb, sheet);
            transportDownloadHandler.dealReportContent(wb, sheet, dataList);
            String userAgent = request.getHeader("USER-AGENT");
            String fileName = "运输计划_" + System.currentTimeMillis();
            if (userAgent.contains("Mozilla")) {
                //google,火狐浏览器
                fileName = new String(fileName.getBytes(), "ISO8859-1");
            } else {
                fileName = URLEncoder.encode(fileName, "UTF8");//其他浏览器
            }
            response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + ".xls\"");
            response.setContentType("APPLICATION/OCTET-STREAM; charset=UTF8");
            response.setHeader("Pragma", "");
            response.setHeader("Cache-Control", "");
            os = response.getOutputStream();
            wb.write(os);
            os.flush();
            response.flushBuffer();
        } catch (Exception e) {
            logger.error("exportExcel error:", e);
        } finally {
            if (os != null) {
                os.flush();
                os.close();
                os = null;
            }
        }
    }

    //    @Override
//    public JSONObject startTransportPlan(HttpServletRequest request) throws Exception {
//        JSONObject obj = JsonUtil.getJSONObject(request);
//        logger.info("TransportPlanServiceImpl startTransportPlan start obj:{}", obj);
//
//        String planIds = JsonUtil.getJSONObjectString(obj, "planIds");
//        String[] planIdsArr = planIds.split(",");
//
//        StringBuffer sb1 = new StringBuffer();
//        StringBuffer sb2 = new StringBuffer();
//        for (String planId : planIdsArr) {
//            TransportPlanDto transportPlanDto = new TransportPlanDto();
//            transportPlanDto.setId(planId);
//            //查询运输计划，看计划是否关闭，关闭不可以在开始
//            transportPlanDto = iTransportPlanDao.queryTransportPlanDetails(transportPlanDto);
//            if ("2".equals(transportPlanDto.getTransportState())) {
//                sb1.append(planId).append(",");
//                break;
//            }
//            //查询运输计划是否存在运输船舶，不存在不可以开始
//            List<TransportPlanShipScheduleDto> list = iTransportPlanDao.queryPlanShip(planId);
//            if (ListUtil.isEmpty(list)) {
//                sb2.append(planId).append(",");
//                break;
//            }
//            //把状态改为已开始
//            TransportPlanDto transportPlanDto1 = new TransportPlanDto();
//            transportPlanDto1.setTransportState("1");
//            transportPlanDto1.setRealStartTime(DateUtil.getStandardNowTime());
//            transportPlanDto1.setId(planId);
//            iTransportPlanDao.updateTransportPlan(transportPlanDto1);
//        }
//        JSONObject retObj = new JSONObject();
//        String msg1 = "";
//        String msg2 = "";
//        if (sb1.length() > 0) {
//            msg1 = sb1.substring(0,sb1.length() - 1) + "已经关闭,开始计划失败！";
//            retObj.put("MSG1", msg1);
//        }
//        if (sb2.length() > 0) {
//            msg2 = sb2.substring(0,sb2.length() - 1) + "计划中不存在承运船舶，请先添加！";
//            retObj.put("MSG2", msg2);
//        }
//
//        retObj.put("SUCCESS", true);
//        retObj.put("MSG", "计划开始");
//        logger.info("TransportPlanServiceImpl startTransportPlan end,msg1:{},msg2:{}",msg1,msg2);
//        return retObj;
//    }

//    @Override
//    public JSONObject endTransportPlan(HttpServletRequest request) throws Exception {
//        JSONObject obj = JsonUtil.getJSONObject(request);
//        logger.info("TransportPlanServiceImpl endTransportPlan start obj:{}", obj);
//        String planIds = JsonUtil.getJSONObjectString(obj, "planIds");
//        String[] planIdsArr = planIds.split(",");
//
//        for (String planId : planIdsArr) {
//            TransportPlanDto transportPlanDto = new TransportPlanDto();
//            //List<TransportPlanShipScheduleDto> list = iTransportPlanDao.queryPlanShip(planId);
//
//            transportPlanDto.setTransportState("2");
//            transportPlanDto.setRealEndDate(DateUtil.getStandardNowTime());
//            transportPlanDto.setId(planId);
//            iTransportPlanDao.updateTransportPlan(transportPlanDto);
//        }
//
//
//        JSONObject retObj = new JSONObject();
//        retObj.put("SUCCESS", true);
//        retObj.put("MSG", "计划结束");
//        logger.info("TransportPlanServiceImpl endTransportPlan end");
//        return retObj;
//    }

}
